+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Audio;
+
+namespace SuperPolarity
+{
+ class MainShip : Ship
+ {
+
+ public static Color BlueColor;
+ public static Color RedColor;
+
+ ParticleEngine particleEngine;
+
+ protected bool Shooting;
+ protected int ShotCooldown;
+
+ protected float CurrentImmortalTime;
+ protected float MaxImmortalTime;
+ protected bool Flashing;
+
+ protected SoundEffect PolarityChange;
+ protected SoundEffect ShootSound;
+ protected SoundEffect Hit;
+
+ public MainShip(SuperPolarity newGame) : base(newGame) {}
+
+ ~MainShip()
+ {
+ particleEngine = null;
+ }
+
+ public override void Initialize(Texture2D texture, Vector2 position)
+ {
+ base.Initialize(texture, position);
+
+ MainShip.BlueColor = new Color(211, 230, 234);
+ MainShip.RedColor = new Color(235, 160, 185);
+
+ PolarityChange = game.Content.Load<SoundEffect>("Sound\\polaritychange");
+ ShootSound = game.Content.Load<SoundEffect>("Sound\\bullet");
+ Hit = game.Content.Load<SoundEffect>("Sound\\hit");
+
+ InitParticleEngine();
+ SetPolarity(Polarity.Positive);
+
+ ActVelocity = 2.5f;
+
+ ShotCooldown = 50;
+ MaxImmortalTime = 1500;
+
+ BoxDimensions.X = 2;
+ BoxDimensions.Y = 2;
+ BoxDimensions.W = 2;
+ BoxDimensions.Z = 2;
+ InitBox();
+
+ BindInput();
+ }
+
+ void InitParticleEngine()
+ {
+ particleEngine = ParticleEffectFactory.CreatePolarCircle(Position);
+ }
+
+ void BindInput()
+ {
+ InputController.Bind("moveX", HandleHorizontalMovement);
+ InputController.Bind("moveY", HandleVerticalMovement);
+ InputController.Bind("changePolarity", HandleChangePolarity);
+ InputController.Bind("shoot", HandleShot);
+ }
+
+ protected void HandleShot(float value)
+ {
+
+ Shooting = true;
+ Timer t = new Timer(new TimerCallback(UnlockShot));
+ t.Change(ShotCooldown, Timeout.Infinite);
+
+ if (Children.Count > 10)
+ {
+ return;
+ }
+
+ var bullet = ActorFactory.CreateBullet(Position, Angle);
+
+ Children.Add(bullet);
+ bullet.Parent = this;
+
+ ShootSound.Play();
+ }
+
+ protected void UnlockShot(object state)
+ {
+ InputController.Unlock("shoot");
+ Shooting = false;
+ }
+
+ protected void HandleChangePolarity(float value)
+ {
+ SwitchPolarity();
+ }
+
+ public void HandleHorizontalMovement(float value)
+ {
+ if (value >= -0.5 && value <= 0.5)
+ {
+ value = 0;
+ }
+
+ Velocity.X = value * MaxVelocity;
+ }
+
+ public void HandleVerticalMovement(float value)
+ {
+ if (value >= -0.5 && value <= 0.5)
+ {
+ value = 0;
+ }
+
+ Velocity.Y = value * MaxVelocity;
+ }
+
+ public override void SwitchPolarity()
+ {
+ base.SwitchPolarity();
+ SwitchParticleEngine(CurrentPolarity);
+ PolarityChange.Play();
+ game.Player.ResetMultiplier();
+ }
+
+ public override void SetPolarity(Polarity newPolarity)
+ {
+ base.SetPolarity(newPolarity);
+ SwitchParticleEngine(newPolarity);
+ }
+
+ protected void SwitchParticleEngine(Polarity polarity)
+ {
+ if (polarity == Polarity.Positive)
+ {
+ particleEngine.Color = MainShip.RedColor;
+ }
+ else if (polarity == Polarity.Negative)
+ {
+ particleEngine.Color = MainShip.BlueColor;
+ }
+ else
+ {
+ particleEngine.Color = Color.Gray;
+ }
+ }
+
+ public override void Update(GameTime gameTime)
+ {
+ base.Update(gameTime);
+ particleEngine.EmitterLocation = Position;
+ particleEngine.Update();
+ ConstrainToEdges();
+ UpdateImmortality(gameTime);
+ }
+
+ public void UpdateImmortality(GameTime gameTime)
+ {
+ if (Immortal)
+ {
+ CurrentImmortalTime += gameTime.ElapsedGameTime.Milliseconds;
+
+ if (Flashing)
+ {
+ Color = new Color(255, 255, 255, 128);
+ }
+ else
+ {
+ Color = Color.White;
+ }
+
+ Flashing = !Flashing;
+
+ if (CurrentImmortalTime > MaxImmortalTime)
+ {
+ Immortal = false;
+ Color = Color.White;
+ }
+ }
+ }
+
+ public override void Move(GameTime gameTime)
+ {
+ var VelocityLimit = MaxVelocity;
+ var SavedVelocity = new Vector2(Velocity.X, Velocity.Y);
+
+ if (Shooting)
+ {
+ VelocityLimit = ActVelocity;
+ }
+
+ if (SavedVelocity.X > VelocityLimit)
+ {
+ SavedVelocity.X = VelocityLimit;
+ }
+
+ if (SavedVelocity.X < -VelocityLimit)
+ {
+ SavedVelocity.X = -VelocityLimit;
+ }
+
+ if (SavedVelocity.Y > VelocityLimit)
+ {
+ SavedVelocity.Y = VelocityLimit;
+ }
+
+ if (SavedVelocity.Y < -VelocityLimit)
+ {
+ SavedVelocity.Y = -VelocityLimit;
+ }
+
+ Position.X = Position.X + SavedVelocity.X;
+ Position.Y = Position.Y + SavedVelocity.Y;
+ }
+
+ public override void Magnetize(Ship ship, float distance, float angle)
+ {
+ }
+
+ protected void ConstrainToEdges()
+ {
+ if (Position.X < 0)
+ {
+ Position.X = 0;
+
+ if (Velocity.X < 0)
+ {
+ Velocity.X = 0;
+ }
+ }
+ if (Position.X > game.GraphicsDevice.Viewport.Width)
+ {
+ Position.X = game.GraphicsDevice.Viewport.Width;
+
+ if (Velocity.X > 0)
+ {
+ Velocity.X = 0;
+ }
+ }
+ if (Position.Y < 0)
+ {
+ Position.Y = 0;
+
+ if (Velocity.Y < 0)
+ {
+ Velocity.Y = 0;
+ }
+ }
+ if (Position.Y > game.GraphicsDevice.Viewport.Height)
+ {
+ Position.Y = game.GraphicsDevice.Viewport.Height;
+
+ if (Velocity.Y < 0)
+ {
+ Velocity.Y = 0;
+ }
+ }
+ }
+
+ public override void Draw(SpriteBatch spriteBatch)
+ {
+ particleEngine.Draw(spriteBatch);
+ base.Draw(spriteBatch);
+ }
+
+ public override void Collide(Actor other, Rectangle collision)
+ {
+ if (other.GetType().IsAssignableFrom(typeof(StandardShip)) &&
+ !Immortal)
+ {
+ Die();
+ }
+ }
+
+ protected override void Die()
+ {
+ game.Player.Lives = game.Player.Lives - 1;
+ game.Player.ResetMultiplier();
+ if (game.Player.Lives < 0)
+ {
+ Dying = true;
+ game.GameOver();
+ }
+ else {
+ Hit.Play();
+ Immortal = true;
+ CurrentImmortalTime = 0;
+ }
+ }
+
+ public override void CleanUp()
+ {
+ base.CleanUp();
+ particleEngine = null;
+ InputController.Unbind("moveX", HandleHorizontalMovement);
+ InputController.Unbind("moveY", HandleVerticalMovement);
+ InputController.Unbind("changePolarity", HandleChangePolarity);
+ InputController.Unbind("shoot", HandleShot);
+ }
+ }
+}